import random
from time import sleep
import json
import logging
_LOGGER = logging.getLogger(__name__)

from .utils import get_mac_addr
from .mqtt import MqttClient

from homeassistant.const import (ATTR_ENTITY_ID,ATTR_FRIENDLY_NAME,ATTR_DOMAIN,CONF_USERNAME,CONF_PASSWORD,CONF_DEVICES)

from .const import (
    DEV_LIST,
    sub_topic,
    pub_topic,
    CONF_SELECT
)


class VioceApp(MqttClient):
    def __init__(self, hass,conf) -> None:
        super().__init__(hass, conf[CONF_USERNAME], conf[CONF_PASSWORD])
        self.dev_list = []
        self.select_all = conf[CONF_SELECT]  #是否全选
        self.devices = conf[CONF_DEVICES]

    def ha_state_changed(self,event):
        """状态变化"""
        domain = event.data[ATTR_ENTITY_ID].split('.')[0]
        
        if not domain in DEV_LIST:
            return
        if not self.flag:
            return
        if not self.dev_list:
            self.get_devices()
        
        for obj in self.dev_list:
            if obj[ATTR_ENTITY_ID] == event.data[ATTR_ENTITY_ID]:
                data = self.json_loads(event.data)
                obj['attributes'] = data['new_state']['attributes']
                obj['state'] = data['new_state']['state']
                self.client.publish(pub_topic + self.username + '/devUpdate', json.dumps(obj))

    def get_devices(self):
        """获取设备列表"""
        states = self._hass.states.all()
        states = self.json_loads(states)

        tmp = []
        if not self.select_all: #未全选
            for state in states:
                for dev in self.devices:
                    if state[ATTR_ENTITY_ID] == dev[ATTR_ENTITY_ID]:
                        state['attributes'][ATTR_FRIENDLY_NAME] = dev[ATTR_FRIENDLY_NAME]
                        tmp.append(state)
            states = tmp

        self.dev_list = []

        i = 0
        for dev in states:
            domain = dev[ATTR_ENTITY_ID].split('.')[0]
            if domain in DEV_LIST:
                """加ID"""
                dev['id'] = '{}-ha-{}-{}-{}'.format(self.username , get_mac_addr(),domain, i)
                dev['name'] = dev['attributes'][ATTR_FRIENDLY_NAME]
                dev[ATTR_DOMAIN] = domain
                self.dev_list.append(dev)
                i = i + 1
        return self.dev_list

    def call_service(self,domain,service,data):
        try:
            #print(domain,service,data)
            self._hass.services.call(domain, service, data, blocking=True)
            return 0
        except Exception as e:
            _LOGGER.error(e)
            return -1

    def get_props(self,device):
        """获取属性状态"""
        dev = { 'dev':dev for dev in self.dev_list if dev['id'] == device['id'] }
        if not dev:
            device['value'] = 'null'
            return device
        dev = dev['dev']
        get_props_fuc = None
        if dev[ATTR_DOMAIN] == 'light' :
            from .switch import get_props
            get_props_fuc = get_props
        elif dev[ATTR_DOMAIN] == 'switch':
            from .switch import get_props
            get_props_fuc = get_props
        elif dev[ATTR_DOMAIN] == 'climate':
            from .climate import get_props
            get_props_fuc = get_props
        elif dev[ATTR_DOMAIN] == 'cover':
            from .climate import get_props
            get_props_fuc = get_props
        return get_props_fuc(dev,device)

    def set_props(self,device): 
        """设置属性状态"""
        dev = { 'dev':dev for dev in self.dev_list if dev['id'] == device['id'] }
        if dev:
            to_call_service_data = None
            
            if dev['dev'][ATTR_DOMAIN] == 'light' :
                from .light import set_props_to_call_service_data
                to_call_service_data = set_props_to_call_service_data
            elif dev['dev'][ATTR_DOMAIN] == 'switch':
                from .switch import set_props_to_call_service_data
                to_call_service_data = set_props_to_call_service_data
            elif dev['dev'][ATTR_DOMAIN] == 'climate':
                from .climate import set_props_to_call_service_data
                to_call_service_data = set_props_to_call_service_data
            elif dev['dev'][ATTR_DOMAIN] == 'cover':
                from .climate import set_props_to_call_service_data
                to_call_service_data = set_props_to_call_service_data
            
            data = to_call_service_data(dev['dev'],device)
            #_LOGGER.error(data)
            device['status'] = self.call_service(data[0],data[1],data[2])
        return device

    def on_message(self,client, userdata, msg):
        
        payload = json.loads(msg.payload.decode())
        if 'type' in payload:
            if not self.dev_list:
                self.get_devices()
            if payload['type'] == 'getDevices':
                payload['data'] = self.get_devices()
            elif payload['type'] == 'getProps':
                """获取属性状态"""
                for device in payload['data']:
                    device = self.get_props(device) 
            elif payload['type'] == 'setProps':
                """设置状态"""
                for device in payload['data']:
                    device = self.set_props(device)
        #_LOGGER.error(payload)
        self.publish(payload)